package mbp.gui.frames;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.DefaultCellEditor;
import javax.swing.JFileChooser;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JButton;
import javax.swing.border.TitledBorder;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import mbp.agents.MbpManagerAgent;
import mbp.base.FeatureType;
import mbp.base.ResourceType;
import mbp.core.Intention;
import mbp.core.JarFolder;
import mbp.core.Resource;
import mbp.core.ResourceTypeBuilder;
import mbp.core.ResourceUtility;
import mbp.core.ResourceValidation;
import mbp.core.Service;
import mbp.core.ServiceTypeBuilder;
import mbp.exceptions.InvalidEnumTypeException;
import mbp.exceptions.InvalidFeatureNameException;
import mbp.exceptions.InvalidFeatureTypeException;
import mbp.exceptions.InvalidFeatureValueException;
import mbp.gui.base.EachRowEditor;
import mbp.gui.panels.BusinessAgentGuiExpl;
import mbp.gui.panels.ResourceBuilderGui;
import mbp.gui.panels.ResourceFunctionViewerGui;
import mbp.gui.panels.ResourceUtilityGui;
import mbp.gui.panels.ResourceValidateGui;
import mbp.gui.panels.ObjectViewerGui;
import mbp.gui.panels.ServiceBuilderGui;
import mbp.gui.panels.ServiceServerGui;
import mbp.gui.panels.ServiceViewerGui;
import mbp.gui.panels.BusinessAgentGui;
import mbp.message.MessageXml;
import mbp.recorder.AgentRecorder;
import mbp.recorder.ObjectSaver;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BoxLayout;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Font;
import java.awt.Component;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;
import javax.swing.border.EtchedBorder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.swing.border.LineBorder;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.JSeparator;

public class MbpManagerGui extends JFrame implements ActionListener
{

	private JPanel contentPane;
	public MbpManagerAgent myAgent;
	private JButton btnStart, btnSave, btnTest, btnLoad, btnStartRc, btnStopRc, btnContinueRc;
	private JComboBox cmbAgentClass;
	private JTextField txtAgentName;
	private DefaultTableModel model;
	private HashMap<String, Resource> resourcesStore;
	private Resource resource;
	//public AgentRecorder agentRecorder;
	
	//private 
	
	public ObjectViewerGui resourceViewerGui;
	public ResourceBuilderGui resourceBuilderGui;
	public ResourceUtilityGui resourceUtilityGui;
	public ResourceValidateGui resourceValidateGui;
	public ResourceFunctionViewerGui resourceFunctionViewerGui;
	public ServiceBuilderGui serviceBuilderGui;
	public ServiceServerGui serviceServerGui;
	public BusinessAgentGui businessAgentGui;
	public BusinessAgentGuiExpl businessAgentGuiExpl;
	public ServiceViewerGui serviceViewerGui;
	
	Logger logger = Logger.getLogger(this.getClass());
	private JButton btnRestore;
	private JTextField txtParam;
	private JTextField txtAgentclass;

	/**
	 * Launch the application.
	 */
//	public static void main(String[] args) {
//		EventQueue.invokeLater(new Runnable() {
//			public void run() {
//				try {
//					MbpManagerGui frame = new MbpManagerGui();
//					frame.setVisible(true);
//				} catch (Exception e) {
//					e.printStackTrace();
//				}
//			}
//		});
//	}

	/**
	 * Create the frame.
	 */
	public MbpManagerGui(MbpManagerAgent a) 
	{
		super(a.getLocalName());
		resourcesStore = new HashMap<String, Resource>();
		myAgent = a;
		//agentRecorder = new AgentRecorder(this);
		//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 780, 500);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		contentPane.add(tabbedPane, BorderLayout.CENTER);
		
		JPanel panelAgents = new JPanel();
		tabbedPane.addTab("Manager", null, panelAgents, null);
		panelAgents.setLayout(null);
		
		JPanel panel = new JPanel();
		panel.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "MBP System Agents", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
		panel.setBounds(10, 11, 350, 159);
		panelAgents.add(panel);
		panel.setLayout(null);
		
		cmbAgentClass = new JComboBox();
		cmbAgentClass.setBounds(10, 38, 240, 22);
		//cmbAgentClass.addItem("mbp.tests.ResourceAgent");
		cmbAgentClass.addItem("mbp.agents.MbpServerAgent");
		cmbAgentClass.addItem("mbp.agents.MbpStorageAgent");
		cmbAgentClass.addItem("mbp.agents.MbpTaskAgent");
		cmbAgentClass.addItem("mbp.agents.TestAgent");
		
		//cmbAgentClass.addItem("");
		//cmbAgentClass.addItem("");
		panel.add(cmbAgentClass);
		
		JLabel lblAgentClass = new JLabel("Agent class");
		lblAgentClass.setBounds(10, 23, 100, 14);
		panel.add(lblAgentClass);
		
		txtAgentName = new JTextField();
		txtAgentName.setBounds(10, 120, 139, 23);
		panel.add(txtAgentName);
		txtAgentName.setColumns(10);
		
		JLabel lblAgentName_1 = new JLabel("Agent name");
		lblAgentName_1.setBounds(10, 105, 100, 14);
		panel.add(lblAgentName_1);
		
		btnStart = new JButton("Start");
		btnStart.setFont(new Font("Dialog", Font.PLAIN, 11));
		btnStart.setToolTipText("Starting new agent");
		btnStart.setBounds(159, 120, 91, 23);
		panel.add(btnStart);
		
		txtAgentclass = new JTextField();
		txtAgentclass.setText("AgentClass");
		txtAgentclass.setBounds(10, 71, 240, 23);
		panel.add(txtAgentclass);
		txtAgentclass.setColumns(10);
		
		btnTest = new JButton("TEST");
		btnTest.setBounds(510, 42, 91, 23);
		panelAgents.add(btnTest);
		
		JPanel panel_1 = new JPanel();
		panel_1.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "Recorder", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
		panel_1.setBounds(10, 181, 350, 186);
		panelAgents.add(panel_1);
		panel_1.setLayout(null);
		
		btnSave = new JButton("Save");
		btnSave.setFont(new Font("Dialog", Font.PLAIN, 11));
		btnSave.setToolTipText("Saving objects to xml file");
		btnSave.setBounds(111, 46, 89, 23);
		panel_1.add(btnSave);
		
		btnLoad = new JButton("Load");
		btnLoad.setFont(new Font("Dialog", Font.PLAIN, 11));
		btnLoad.setToolTipText("Restoring objects from xml file");
		btnLoad.setBounds(10, 46, 89, 23);
		panel_1.add(btnLoad);
		
		btnStartRc = new JButton("Rec");
		btnStartRc.setFont(new Font("Dialog", Font.PLAIN, 11));
		btnStartRc.setToolTipText("Start recording");
		btnStartRc.setBounds(10, 142, 89, 23);
		panel_1.add(btnStartRc);
		
		btnStopRc = new JButton("Stop");
		btnStopRc.setFont(new Font("Dialog", Font.PLAIN, 11));
		btnStopRc.setToolTipText("Stop recording and save");
		btnStopRc.setBounds(210, 142, 89, 23);
		panel_1.add(btnStopRc);
		
		btnRestore = new JButton("Restore");
		btnRestore.setFont(new Font("Dialog", Font.PLAIN, 11));
		btnRestore.setToolTipText("Restoring agents from xml file");
		btnRestore.setBounds(10, 108, 89, 23);
		panel_1.add(btnRestore);
		
		JSeparator separator = new JSeparator();
		separator.setBounds(10, 33, 330, 2);
		panel_1.add(separator);
		
		JLabel lblObjects = new JLabel("Objects");
		lblObjects.setBounds(10, 18, 100, 14);
		panel_1.add(lblObjects);
		
		JSeparator separator_1 = new JSeparator();
		separator_1.setBounds(10, 95, 330, 2);
		panel_1.add(separator_1);
		
		JLabel lblAgents = new JLabel("Agents");
		lblAgents.setBounds(10, 80, 100, 14);
		panel_1.add(lblAgents);
		
		btnContinueRc = new JButton("Continue");
		btnContinueRc.setFont(new Font("Dialog", Font.PLAIN, 11));
		btnContinueRc.setToolTipText("Open file and continue recording");
		btnContinueRc.setBounds(111, 142, 89, 23);
		panel_1.add(btnContinueRc);
		
		txtParam = new JTextField();
		txtParam.setBounds(510, 11, 86, 20);
		panelAgents.add(txtParam);
		txtParam.setColumns(10);
		
		btnLoad.addActionListener(this);
		btnSave.addActionListener(this);
		btnTest.addActionListener(this);
		btnStart.addActionListener(this);
		btnStartRc.addActionListener(this);
		btnStopRc.addActionListener(this);
		btnRestore.addActionListener(this);
		btnContinueRc.addActionListener(this);
		
		JTabbedPane tabbedlResources = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.addTab("Objects", null, tabbedlResources, null);
		
		resourceBuilderGui = new ResourceBuilderGui(this);
		tabbedlResources.addTab("Resource", null, resourceBuilderGui, null);
		
		resourceUtilityGui = new ResourceUtilityGui(this);
		tabbedlResources.addTab("Resource Utility", null, resourceUtilityGui, null);
		
		resourceValidateGui = new ResourceValidateGui(this);
		tabbedlResources.addTab("Resource Validation", null, resourceValidateGui, null);
		
		resourceViewerGui = new ObjectViewerGui(myAgent);
		tabbedlResources.addTab("Agent object explorer", null, resourceViewerGui, null);
		
		//resourceFunctionViewerGui = new ResourceFunctionViewerGui(this);
		//tabbedlResources.addTab("Function viewer", null, resourceFunctionViewerGui, null);
		
		JTabbedPane tabbedServices = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.addTab("Services", null, tabbedServices, null);
		
		serviceBuilderGui = new ServiceBuilderGui(this);
		tabbedServices.addTab("Service builder", null, serviceBuilderGui, null);
		
		serviceServerGui = new ServiceServerGui(this);
		tabbedServices.addTab("Service Agent", null, serviceServerGui, null);
		
		JTabbedPane tabbedBPA = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.addTab("Business Process Agent", null, tabbedBPA, null);
		
		businessAgentGui = new BusinessAgentGui(this);
		tabbedBPA.addTab("Agent Start", null, businessAgentGui, null);
		
		businessAgentGuiExpl = new BusinessAgentGuiExpl(this);
		tabbedBPA.addTab("Agent explore", null, businessAgentGuiExpl, null);
		
		serviceViewerGui = new ServiceViewerGui(this);
		tabbedServices.addTab("Agent explorer", null, serviceViewerGui, null);
				
		model = new DefaultTableModel();
		model.addColumn("Feature Name");
		model.addColumn("Feature Type");
		model.addColumn("Feature Value");
		
		
		ResourceTypeBuilder typeBuilder = new ResourceTypeBuilder("");
		List<String> types = typeBuilder.GetResourceTypeNames();
		resourceBuilderGui.LoadResourceTypeList(types);
		resourceUtilityGui.LoadResourceTypeList(types);
		resourceValidateGui.LoadResourceTypeList(types);
		businessAgentGui.loadResourceTypeList(types);
	
		
		ServiceTypeBuilder serviceTypeBuilder = new ServiceTypeBuilder("");
		List<String> stypes = serviceTypeBuilder.GetServiceTypeNames();
		serviceBuilderGui.LoadServiceTypeList(stypes);
		serviceServerGui.LoadServiceTypeList(stypes);
		//businessAgentGui.LoadServiceTypeList(stypes);
		
		addWindowListener(new	WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				myAgent.doDelete();
			}
		} );
		
		txtAgentclass.setText((String) cmbAgentClass.getSelectedItem());
		cmbAgentClass.addItemListener(new ItemListener() {
			
			@Override
			public void itemStateChanged(ItemEvent arg0) {
				//int index = cmbAgentClass.getSelectedIndex();
				txtAgentclass.setText((String) cmbAgentClass.getSelectedItem());
				
			}
		});
		
		
		
		//loadMbpObjects("Manager.xml");
		logger.info("MbpManagerGui is ready.");
	}

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		
		
		if(e.getSource() == btnStart)
		{
			String agentClass = txtAgentclass.getText();
			String agentName = txtAgentName.getText();
			
			if(txtParam.getText() != null)
			{
				Object[] args = new Object[1];
				args[0] = txtParam.getText();
				myAgent.StartAgent(agentClass, agentName, args);
			}
			else
			{
				myAgent.StartAgent(agentClass, agentName, null);
			}
		}
		
		if(e.getSource() == btnLoad)
		{
			JarFolder jf = new JarFolder();
			File f = new File(jf.getJarFolder() + "conf" + File.separatorChar);
			JFileChooser chooser = new JFileChooser(f);
			FileFilter filter = new FileNameExtensionFilter("xml files", "xml");
			chooser.setFileFilter(filter);
		    int returnVal = chooser.showDialog(this, "Load");
		    if(returnVal == JFileChooser.APPROVE_OPTION) {
		    	//loadMbpObjects(chooser.getSelectedFile().getAbsolutePath());
		    	ObjectSaver os = new ObjectSaver(this);
		    	os.loadMbpObjects(chooser.getSelectedFile().getAbsolutePath());
		    }
		    
		    
		    
		    return;
		}
		
		if(e.getSource() == btnSave)
		{
			JarFolder jf = new JarFolder();
			File f = new File(jf.getJarFolder() + "conf" + File.separatorChar);
			JFileChooser chooser = new JFileChooser(f);
			FileFilter filter = new FileNameExtensionFilter("xml files", "xml");
			chooser.setFileFilter(filter);
		    int returnVal = chooser.showDialog(this, "Save");
		    if(returnVal == JFileChooser.APPROVE_OPTION) {
		       System.out.println("You chose to open this file: " +
		            chooser.getSelectedFile().getName());
		       //saveMbpObjects(chooser.getSelectedFile().getAbsolutePath());
		       
		       ObjectSaver os = new ObjectSaver(this);
		       os.saveMbpObjects(chooser.getSelectedFile().getAbsolutePath());
		    }
		    return;
		}
		
		if(e.getSource() == btnStartRc)
		{
			myAgent.startRecording();
			
			btnRestore.setEnabled(false);
			btnContinueRc.setEnabled(false);
			btnStartRc.setEnabled(false);
			return;
		}
		
		if(e.getSource() == btnContinueRc)
		{
			JarFolder jf = new JarFolder();
			File f = new File(jf.getJarFolder() + "conf" + File.separatorChar);
			JFileChooser chooser = new JFileChooser(f);
			FileFilter filter = new FileNameExtensionFilter("xml files", "xml");
			chooser.setFileFilter(filter);
		    int returnVal = chooser.showDialog(this, "Continue");
		    if(returnVal == JFileChooser.APPROVE_OPTION) {
		       System.out.println("You chose to open this file: " +
		            chooser.getSelectedFile().getName());
		       //saveMbpObjects(chooser.getSelectedFile().getAbsolutePath());
		       
		       myAgent.continueRecording(chooser.getSelectedFile().getAbsolutePath());
		       
		       btnRestore.setEnabled(false);
		       btnContinueRc.setEnabled(false);
		       btnStartRc.setEnabled(false);
		    }
			return;
		}
		
		if(e.getSource() == btnStopRc)
		{
			JarFolder jf = new JarFolder();
			File f = new File(jf.getJarFolder() + "conf" + File.separatorChar);
			JFileChooser chooser = new JFileChooser(f);
			FileFilter filter = new FileNameExtensionFilter("xml files", "xml");
			chooser.setFileFilter(filter);
		    int returnVal = chooser.showDialog(this, "Save");
		    if(returnVal == JFileChooser.APPROVE_OPTION) {
		       System.out.println("You chose to open this file: " +
		            chooser.getSelectedFile().getName());
		       //saveMbpObjects(chooser.getSelectedFile().getAbsolutePath());
		       
		       myAgent.stopRecording(chooser.getSelectedFile().getAbsolutePath());
		       btnRestore.setEnabled(true);
		       btnContinueRc.setEnabled(true);
		       btnStartRc.setEnabled(true);
		    }
			return;
		}
		
		if(e.getSource() == btnRestore)
		{
			JarFolder jf = new JarFolder();
			File f = new File(jf.getJarFolder() + "conf" + File.separatorChar);
			JFileChooser chooser = new JFileChooser(f);
			FileFilter filter = new FileNameExtensionFilter("xml files", "xml");
			chooser.setFileFilter(filter);
		    int returnVal = chooser.showDialog(this, "Restore");
		    if(returnVal == JFileChooser.APPROVE_OPTION) {
		       System.out.println("You chose to open this file: " +
		            chooser.getSelectedFile().getName());
		       AgentRecorder agentRecorder = new AgentRecorder();
		       agentRecorder.restoreAgents(myAgent, chooser.getSelectedFile().getAbsolutePath());
		       //saveMbpObjects(chooser.getSelectedFile().getAbsolutePath())
		    }
			return;
		}
		// TODO Auto-generated method stub
		
		if(e.getSource() == btnTest)
		{
			//ServiceTypeBuilder stb = new ServiceTypeBuilder("");
			//Intention in = new Intention(stb.GetServiceType("S-HOUSE"));
			//in.setClientName(myAgent.getLocalName());
			//in.getResourcesOut().get(0).setCondition("{FLOOR>3}&&{FLOOR<6}&&{SIZE>250}");
			
			myAgent.sendDoDelete(txtParam.getText());
		}
		
	}
	
	
	/**
	 * Zapisuje obiekty: Resource, ResourceValidation, ResourceUtility, Service do pliku
	 * @param fileName
	 */
	public void saveMbpObjects(String fileName)
	{
		//JarFolder jf = new JarFolder();
		//fileName = jf.getJarFolder() + "conf" + File.separatorChar + fileName;
		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db;
		try {
			db = dbf.newDocumentBuilder();
			Document doc = db.newDocument();
			
			//Stworzenie root
			Element rootElement = doc.createElement("manager");
			doc.appendChild(rootElement);
			
			Element resourcesElement = doc.createElement("resources");
			Element validationsElement = doc.createElement("validations");
			Element utilitiesElement = doc.createElement("utilities");
			Element servicesElement = doc.createElement("services");
			
			rootElement.appendChild(resourcesElement);
			rootElement.appendChild(validationsElement);
			rootElement.appendChild(utilitiesElement);
			rootElement.appendChild(servicesElement);
			
			//----Resources--------------------------------------------------------------------------------------------
			ArrayList<Resource> resourcesList = resourceBuilderGui.getResourcesList();
			for(int i = 0; i<resourcesList.size(); i++)
			{
				Resource rc = resourcesList.get(i);
				
				Element resourceElement = doc.createElement("resource");
				resourceElement.setAttribute("type", rc.getType().getResourceTypeName());
				
				Element resourceidElement = doc.createElement("resourceid");
				Element ownerElement = doc.createElement("owner");
				Element vdateElement = doc.createElement("vdate");
				
				resourceidElement.setTextContent(rc.getUUID());
				ownerElement.setTextContent(rc.getOwner());
				vdateElement.setTextContent(rc.getValidDateStr());
				
				resourceElement.appendChild(resourceidElement);
				resourceElement.appendChild(ownerElement);
				resourceElement.appendChild(vdateElement);
				
				Element featuresElement = doc.createElement("features");
				resourceElement.appendChild(featuresElement);
				
				Iterator<String> it = rc.getType().getFeaturesCollection().keySet().iterator();
				while(it.hasNext())
				{
					String key = it.next();
					FeatureType type = rc.getFeatureType(key);
					
					Element featureElement = doc.createElement("feature");
					featureElement.setTextContent(key);
					
					Object ob = rc.getFeatureValue(key);
					switch(type)
					{
					case INT:
						featureElement.setAttribute("value", ((Integer)ob).toString());
						break;
					case FLOAT:
						featureElement.setAttribute("value", ((Float)ob).toString());
						break;
					default:
						featureElement.setAttribute("value", ob.toString());
						break;
					}
					
					featuresElement.appendChild(featureElement);
				}
				
				resourcesElement.appendChild(resourceElement);
			}
			
			
			//---validations-------------------------------------------------------------------------------------------
			ArrayList<ResourceValidation> validationsList = resourceValidateGui.getValidationsList();
			for(int i = 0; i<validationsList.size(); i++)
			{
				ResourceValidation rv = validationsList.get(i);
				
				Element validationElement = doc.createElement("validation");
				validationElement.setTextContent(rv.getType().getResourceTypeName());
				validationElement.setAttribute("value", rv.getCondition());
				
				validationsElement.appendChild(validationElement);
			}
				
			
			//---utilities---------------------------------------------------------------------------------------------
			ArrayList<ResourceUtility> utilitiesList = resourceUtilityGui.getUtilitiesList();
			for(int i = 0; i<utilitiesList.size(); i++)
			{
				ResourceUtility ru = utilitiesList.get(i);
				
				//utworzenie tagu utility
				Element utilityElement = doc.createElement("utility");
				utilityElement.setAttribute("type", ru.getType().getResourceTypeName());
				
				Element functionElement = doc.createElement("function");
				functionElement.setAttribute("value", ru.getExrpession());
				utilityElement.appendChild(functionElement);
				
				Element enumsElement = doc.createElement("enums");
				utilitiesElement.appendChild(enumsElement);
				
				Iterator<String> it1 = ru.getTableNames().iterator();
				while(it1.hasNext())
				{
					String key = it1.next();
					
					Iterator<String> it2 = ru.getTableValues(key).keySet().iterator();
					
					while(it2.hasNext())
					{
						String en = it2.next();
						Integer v = ru.getTableValues(key).get(en);
						
						Element enumElement = doc.createElement("enum");
						enumElement.setTextContent(key);
						enumElement.setAttribute("svalue", en);
						enumElement.setAttribute("ivalue", v.toString());
						
						enumsElement.appendChild(enumElement);
					}
					
				}
				utilityElement.appendChild(enumsElement);
				
				utilitiesElement.appendChild(utilityElement);
				
			}
			
			//---services----------------------------------------------------------------------------------------------
			ArrayList<Service> servicesList = serviceBuilderGui.getServicesList();
			for(int i = 0; i<servicesList.size(); i++)
			{
				Service srv = servicesList.get(i);
				
				//utworzenie tagu service
				Element serviceElement = doc.createElement("service");			
				serviceElement.setAttribute("type", srv.getType().getServiceTypeName());
				
				//dodanie tagu service do services
				servicesElement.appendChild(serviceElement);
				
				//utworzenie tagow in i out i dodanie do service
				Element inElement = doc.createElement("in");
				Element outElement = doc.createElement("out");
				serviceElement.appendChild(inElement);
				serviceElement.appendChild(outElement);
				
				//utworzennie tablic z resourceValidation: zaliczka, towar, zaplata
				ArrayList<ResourceValidation> valInAdvance = srv.getResourcesIn(0);
				ArrayList<ResourceValidation> valInStuff = srv.getResourcesIn(1);
				ArrayList<ResourceValidation> valInPay = srv.getResourcesIn(2);
				
				//zapisanie zaliczka
				for(int j = 0; j<valInAdvance.size(); j++)
				{
					ResourceValidation rv = valInAdvance.get(j);
					
					Element validationElement = doc.createElement("validation");
					validationElement.setAttribute("point", (String) rv.getType().getValue());
					validationElement.setAttribute("value", rv.getCondition());
					validationElement.setTextContent(rv.getType().getResourceTypeName());
					
					inElement.appendChild(validationElement);
				}
				
				//zapisanie towar
				for(int j = 0; j<valInStuff.size(); j++)
				{
					ResourceValidation rv = valInStuff.get(j);
					
					Element validationElement = doc.createElement("validation");
					validationElement.setAttribute("point", (String) rv.getType().getValue());
					validationElement.setAttribute("value", rv.getCondition());
					validationElement.setTextContent(rv.getType().getResourceTypeName());
					
					inElement.appendChild(validationElement);
				}
				
				//zapisanie zaplata
				for(int j = 0; j<valInPay.size(); j++)
				{
					ResourceValidation rv = valInPay.get(j);
					
					Element validationElement = doc.createElement("validation");
					validationElement.setAttribute("point", (String) rv.getType().getValue());
					validationElement.setAttribute("value", rv.getCondition());
					validationElement.setTextContent(rv.getType().getResourceTypeName());
					
					inElement.appendChild(validationElement);
				}
				
				//Zapisanie zasobow wyjsciowych
				ArrayList<Resource> resourcesListOut = srv.getResourcesOut();
				for(int j = 0; j<resourcesListOut.size(); j++)
				{
					Resource rc = resourcesListOut.get(j);
					
					Element resourceElement = doc.createElement("resource");
					resourceElement.setAttribute("type", rc.getType().getResourceTypeName());
					
					Element resourceidElement = doc.createElement("resourceid");
					Element ownerElement = doc.createElement("owner");
					Element vdateElement = doc.createElement("vdate");
					
					resourceidElement.setTextContent(rc.getUUID());
					ownerElement.setTextContent(rc.getOwner());
					vdateElement.setTextContent(rc.getValidDateStr());
					
					resourceElement.appendChild(resourceidElement);
					resourceElement.appendChild(ownerElement);
					resourceElement.appendChild(vdateElement);
					
					Element featuresElement = doc.createElement("features");
					resourceElement.appendChild(featuresElement);
					
					Iterator<String> it = rc.getType().getFeaturesCollection().keySet().iterator();
					while(it.hasNext())
					{
						String key = it.next();
						FeatureType type = rc.getFeatureType(key);
						
						Element featureElement = doc.createElement("feature");
						featureElement.setTextContent(key);
						
						Object ob = rc.getFeatureValue(key);
						switch(type)
						{
						case INT:
							featureElement.setAttribute("value", ((Integer)ob).toString());
							break;
						case FLOAT:
							featureElement.setAttribute("value", ((Float)ob).toString());
							break;
						default:
							featureElement.setAttribute("value", ob.toString());
							break;
						}
						
						featuresElement.appendChild(featureElement);
					}
					
					outElement.appendChild(resourceElement);
				}
			}
			
			
			// write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(fileName));
	 
			// Output to console for testing
			//StreamResult result = new StreamResult(System.out);
	 
			transformer.transform(source, result);
	 
			//System.out.println("File saved!");
			logger.info("File saved!");
			
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			logger.error("ParserConfigurationException", e);
		} catch (TransformerConfigurationException e) {
			// TODO Auto-generated catch block
			logger.error("TransformerConfigurationException", e);
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			logger.error("TransformerException", e);
		} catch (InvalidFeatureNameException e) {
			// TODO Auto-generated catch block
			logger.error("InvalidFeatureNameException", e);
		}
	}
	
	/**
	 * Odczytuje z pliku obiekty: Resource, ResourceValidation, ResourceUtility, i �aduje do wlasciwych zak�adek
	 * @param fileName
	 * @throws IOException 
	 * @throws SAXException 
	 */
	public void loadMbpObjects(String fileName)
	{
		//JarFolder jf = new JarFolder();
		//fileName = jf.getJarFolder() + "conf" + File.separatorChar + fileName;
		
		
		File fileObjects = new File(fileName);
		DocumentBuilder db;
		Document docObjects;
		try {
			db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			docObjects = db.parse(fileObjects);
			
			
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			logger.error("ParserConfigurationException", e);
			return;
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			logger.error("SAXException", e);
			return;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			logger.error("IOException", e);
			return;
		}
		
		//Pobranie g��wnych list zawieraj�cych listy obiekt�w
		NodeList resources = docObjects.getElementsByTagName("resources");
		NodeList validations = docObjects.getElementsByTagName("validations");
		NodeList utilities = docObjects.getElementsByTagName("utilities");
		NodeList services = docObjects.getElementsByTagName("services");
		//NodeList offers = docObjects.getElementsByTagName("offers");
		
		//----Resources------------------------------------------------------------------------------------------------
		Element resourcesElement = (Element)resources.item(0);
		NodeList resourceItems = resourcesElement.getElementsByTagName("resource");
		for(int i=0; i<resourceItems.getLength(); i++)
		{
			Element resourceElement = (Element) resourceItems.item(i);
			
			//Pobranie elememtow <resource>
			NodeList resourceidList = resourceElement.getElementsByTagName("resourceid");
			NodeList ownerList = resourceElement.getElementsByTagName("owner");
			NodeList vdateList = resourceElement.getElementsByTagName("vdate");
			NodeList featuresList = resourceElement.getElementsByTagName("features");
			
			//Pobranie typu zasobu i uuid
			String type = resourceElement.getAttribute("type");
			
			Element resourceidElement = (Element) resourceidList.item(0);
			String uuid = resourceidElement.getTextContent();
			
			//Utworzenie zasobu
			ResourceTypeBuilder rtb = new ResourceTypeBuilder("");
			Resource rc = new Resource(rtb.GetResourceType(type), uuid);
			
			Element ownerElement = (Element) ownerList.item(0);
			rc.setOwner(ownerElement.getTextContent());
			
			Element vdateElement = (Element) vdateList.item(0);
			try {
				rc.setValidDateStr(vdateElement.getTextContent());
			} catch (DOMException e) {
				// TODO Auto-generated catch block
				logger.error("DOMException", e);
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				logger.error("ParseException", e);
			}
			
			Element featuresElement = (Element) featuresList.item(0);
			NodeList featureList = featuresElement.getElementsByTagName("feature");
			for(int j=0; j<featureList.getLength(); j++)
			{
				Element featureElement = (Element) featureList.item(j);
				String fname = featureElement.getTextContent();
				String fvalue = featureElement.getAttribute("value");
				
				try {
					FeatureType ftype = rc.getFeatureType(fname);
					
					switch(ftype)
					{
					case INT:
						rc.setFeatureValue(fname, Integer.parseInt(fvalue));
						break;
					case FLOAT:
						rc.setFeatureValue(fname, Float.parseFloat(fvalue));
						break;
					case ENUM:
						rc.setFeatureValue(fname, fvalue);
						break;
					}
					
				} catch (InvalidFeatureNameException e) {
					// TODO Auto-generated catch block
					logger.error("InvalidFeatureNameException", e);
				} catch (NumberFormatException e) {
					// TODO Auto-generated catch block
					logger.error("NumberFormatException", e);
				} catch (InvalidFeatureTypeException e) {
					// TODO Auto-generated catch block
					logger.error("InvalidFeatureTypeException", e);
				} catch (InvalidFeatureValueException e) {
					// TODO Auto-generated catch block
					logger.error("InvalidFeatureValueException", e);
				}
			}
			
		
			resourceBuilderGui.AddResource(rc);
		}
		
		//---validations-----------------------------------------------------------------------------------------------
		Element validationsElement = (Element)validations.item(0);
		NodeList validationItems = validationsElement.getElementsByTagName("validation");
		for(int i = 0; i<validationItems.getLength(); i++)
		{
			//Pobranie elementu validation z validations
			Element validationElement = (Element) validationItems.item(i);
			
			//Odczytanie typu
			String type = validationElement.getTextContent();
			
			//Utworzenie obiektu ResourceValidation
			ResourceTypeBuilder rtb = new ResourceTypeBuilder("");
			ResourceValidation rv = new ResourceValidation(rtb.GetResourceType(type));
			
			//Odczytanie i ustawienie warunku
			rv.setCondition(validationElement.getAttribute("value"));
			
			//Dodanie obiektu ResourceValidation do zakladki resourceValidateGui
			resourceValidateGui.AddValuesRangeFunction(rv);
		}
		
		//---utilities-------------------------------------------------------------------------------------------------
		Element utilitiesElement = (Element)utilities.item(0);
		NodeList utilityItems = utilitiesElement.getElementsByTagName("utility");
		for(int i = 0; i<utilityItems.getLength(); i++)
		{
			//Pobranie utility validation z utilities
			Element utilityElement = (Element) utilityItems.item(i);
			
			//Odczytanie typu
			String type = utilityElement.getAttribute("type");
			
			//Utworzenie obiektu ResourceUtility
			ResourceTypeBuilder rtb = new ResourceTypeBuilder("");
			ResourceUtility ru = new ResourceUtility(rtb.GetResourceType(type));
			
			//Odczytanie i zapisanie do obiektu ResourceUtility funkcji
			NodeList functionItems = utilityElement.getElementsByTagName("function");
			Element functionElement = (Element) functionItems.item(0); 
			ru.setExpression(functionElement.getAttribute("value"));
			
			NodeList enumsItems = utilityElement.getElementsByTagName("enums");
			Element enumsElement = (Element) enumsItems.item(0);
			
			NodeList enumItems = enumsElement.getElementsByTagName("enum");
			for(int j = 0; j<enumItems.getLength(); j++)
			{
				Element enumElement = (Element) enumItems.item(j);
				String featureName = enumElement.getTextContent();
				String svalue = enumElement.getAttribute("svalue");
				Integer ivalue = Integer.parseInt(enumElement.getAttribute("ivalue"));
				
				try {
					ru.setEnumValue(featureName, svalue, ivalue);
				} catch (InvalidFeatureNameException e) {
					// TODO Auto-generated catch block
					logger.error("InvalidFeatureNameException", e);
				} catch (InvalidEnumTypeException e) {
					// TODO Auto-generated catch block
					logger.error("InvalidEnumTypeException", e);
				}
				
				
			}
			
			resourceUtilityGui.AddUtilityFunction(ru);
			
		}
		
		//----Services-------------------------------------------------------------------------------------------------
		Element servicesElement = (Element)services.item(0);
		NodeList serviceItems = servicesElement.getElementsByTagName("service");
		for(int i=0; i<serviceItems.getLength(); i++)
		{
			Element serviceElement = (Element) serviceItems.item(i);
			
			NodeList inList = serviceElement.getElementsByTagName("in");
			NodeList outList = serviceElement.getElementsByTagName("out");
			
			//Pobranie typu serwisu
			String type = serviceElement.getAttribute("type");
			
			ServiceTypeBuilder stb = new ServiceTypeBuilder("");
			Service service = new Service(stb.GetServiceType(type));
			
			ArrayList<ResourceValidation> valInAdvance = service.getResourcesIn(0);
			ArrayList<ResourceValidation> valInStuff = service.getResourcesIn(1);
			ArrayList<ResourceValidation> valInPay = service.getResourcesIn(2);
			int ai = 0;
			int si = 0;
			int pi = 0;
			
			Element inElement = (Element)inList.item(0);
			NodeList validationList = inElement.getElementsByTagName("validation");
			for(int j = 0; j<validationList.getLength(); j++)
			{
				Element validationElement = (Element) validationList.item(j);
				String point = validationElement.getAttribute("point");
				char p = point.charAt(0);
				switch(p)
				{
				case 'a':
					valInAdvance.get(ai).setCondition(validationElement.getAttribute("value"));
					ai++;
					break;
				case 's':
					valInStuff.get(si).setCondition(validationElement.getAttribute("value"));
					si++;
					break;
				case 'p':
					valInPay.get(pi).setCondition(validationElement.getAttribute("value"));
					pi++;
					break;
				}
			}
			
			ArrayList<Resource> resourcesListOut = service.getResourcesOut();
			Element outElement = (Element)outList.item(0);
			NodeList resourceList = outElement.getElementsByTagName("resource");
			for(int j = 0; j<resourceList.getLength(); j++)
			{
				Resource rc = resourcesListOut.get(j);
				Element resourceElement = (Element) resourceList.item(j);
				
				NodeList featuresList = resourceElement.getElementsByTagName("features");
				Element featuresElement = (Element) featuresList.item(0);
				
				NodeList featureList = featuresElement.getElementsByTagName("feature");
				for(int z = 0; z<featureList.getLength(); z++)
				{
					Element featureElement = (Element) featureList.item(z);
					try {
						FeatureType type2 = rc.getFeatureType(featureElement.getTextContent());
						switch(type2)
						{
						case INT:
							rc.setFeatureValue(featureElement.getTextContent(), Integer.parseInt(featureElement.getAttribute("value")));										
							break;
						case FLOAT:
							rc.setFeatureValue(featureElement.getTextContent(), Float.parseFloat(featureElement.getAttribute("value")));
							break;
						case ENUM:
							rc.setFeatureValue(featureElement.getTextContent(), featureElement.getAttribute("value"));
						default:				
							break;
						}
						
					} catch (DOMException e) {
						// TODO Auto-generated catch block
						logger.error("DOMException", e);
					} catch (InvalidFeatureNameException e) {
						// TODO Auto-generated catch block
						logger.error("InvalidFeatureNameException", e);
					} catch (InvalidFeatureValueException e) {
						// TODO Auto-generated catch block
						logger.error("InvalidFeatureValueException", e);
					} catch (InvalidFeatureTypeException e) {
						// TODO Auto-generated catch block
						logger.error("InvalidFeatureTypeException", e);
					}
				}
				//service.
			}
			
			
			serviceBuilderGui.addService(service);
		}
		
	}
	
	
	public void ShowErrorWindow(String err)
	{
		JOptionPane.showMessageDialog( this, err, "ERROR", JOptionPane.ERROR_MESSAGE);
	}

	public Resource getActiveResource() {
		return resource;
	}

	public void setActiveResource(Resource resource) {
		this.resource = resource;
	}
}

